package com.lancoo.ccas53.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lancoo.ccas53.entity.Campus;
import com.lancoo.ccas53.entity.*;
import com.lancoo.ccas53.exception.BizException;
import com.lancoo.ccas53.mapper.*;
import com.lancoo.ccas53.pojo.common.PageInfo;
import com.lancoo.ccas53.pojo.dto.ExcelTeachingDto;
import com.lancoo.ccas53.pojo.dto.SplitSubClass;
import com.lancoo.ccas53.pojo.dto.SubGroupDto;
import com.lancoo.ccas53.pojo.dto.TeacherDto;
import com.lancoo.ccas53.pojo.excel.ErrorExcelVo;
import com.lancoo.ccas53.pojo.excel.ExcelStudent;
import com.lancoo.ccas53.pojo.excel.ExcelSubClass;
import com.lancoo.ccas53.pojo.excel.ExcelTeachingStudentDto;
import com.lancoo.ccas53.pojo.vo.*;
import com.lancoo.ccas53.service.*;
import com.lancoo.ccas53.util.BatchInsert;
import com.lancoo.ccas53.util.MyExcelUtils;
import com.lancoo.ccas53.util.PagingUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

/**
 * <p>
 * 分组上课 服务实现类
 * </p>
 *
 * @author quin.song
 * @since 2024-05-20
 */
@Service
@Slf4j
public class SubClassServiceImpl extends ServiceImpl<SubClassMapper, SubClass> implements SubClassService {

    @Resource
    private SubClassGroupService subClassGroupService;
    @Resource
    private TeacherService teacherService;
    @Resource
    private TeachingClassService teachingClassService;
    @Resource
    private TeachingClassMapper teachingClassMapper;
    @Resource
    private TeachingClassWeekService teachingClassWeekService;
    @Resource
    private PlanTeachingMapper planTeachingMapper;
    @Resource
    private PlanTeachingCourseMapper planTeachingCourseMapper;
    @Resource
    private PlanTeachingStudentMapper planTeachingStudentMapper;
    @Resource
    private AssessmentMethodService assessmentMethodService;

    @Resource
    private CollegeService collegeService;
    @Resource
    private StudentMapper studentMapper;
    @Resource
    private RoomService roomService;
    @Resource
    private RoomMapper roomMapper;
    @Resource
    private TeachingClassTeacherService teachingClassTeacherService;
    @Resource
    private TeachingClassStudentService teachingClassStudentService;
    @Resource
    private TeachingClassStudentMapper teachingClassStudentMapper;
    @Resource
    private PlanTeachingStudentService planTeachingStudentService;
    @Resource
    private PlanTeachingCourseService planTeachingCourseService;
    @Resource
    private CourseWeekService courseWeekService;
    @Resource
    private MajorGradeService majorGradeService;
    @Resource
    private TeachingClassServiceImpl classImplService;
    @Resource
    private TypeService typeService;
    @Resource
    private SubClassService subClassService;


    @Resource
    private TaskInfoService taskInfoService;
    @Resource
    private TeachingClassWeekMapper teachingClassWeekMapper;
    @Resource
    private TeachingClassTeacherMapper teachingClassTeacherMapper;
    @Resource
    private CourseService courseService;

    @Resource
    private CampusService campusService;

    @Resource
    private SubClassGroupTempService subClassGroupTempService;
    @Resource
    private StudentService studentService;
    private static int GROUP_NUM = 1;


    @Override
    public List<SubCourseVo> getByUniqueShiftSign(String uniqueShiftSign) {
        List<SubCourseVo> list = new ArrayList<>();

        List<TeachingClass> teachingClasses = teachingClassService.lambdaQuery().eq(TeachingClass::getUniqueShiftSign, uniqueShiftSign).list();
        List<Long> teachingIds = teachingClasses.stream().map(TeachingClass::getTeachingClassId).collect(Collectors.toList());
        Map<Long, List<TeacherDto>> teacherMap = teacherService.getTeacherByTeachingClassIds(teachingIds)
                .stream().collect(Collectors.groupingBy(TeacherDto::getTeachingClassId));
        //获取授课类型数据
        Map<Long, List<TeachingClassWeek>> teachingClassWeekMap = teachingClassWeekService.lambdaQuery().in(TeachingClassWeek::getTeachingClassId, teachingIds).list()
                .stream().collect(Collectors.groupingBy(TeachingClassWeek::getTeachingClassId));
        //添加课程教师标识 用于确定是否属于统一分组教学班
        for (TeachingClass teachingClass : teachingClasses) {
            String teacherIds = teacherMap.get(teachingClass.getTeachingClassId())
                    .stream().map(TeacherDto::getTeacherId).toString();
            teachingClass.setCourseTeacherIds(teachingClass.getCourseId() + teacherIds);
        }
        Map<String, List<TeachingClass>> teachingClassMap = teachingClasses.stream().collect(Collectors.groupingBy(TeachingClass::getCourseTeacherIds));
        for (Map.Entry<String, List<TeachingClass>> teachingClassEntry : teachingClassMap.entrySet()) {
            List<TeachingClass> groupTeaching = teachingClassEntry.getValue();
            TeachingClass value = groupTeaching.get(0);
            list.add(new SubCourseVo().setCourseId(value.getCourseId())
                    .setCourseName(value.getCourseName())
                    .setTeachers(teacherMap.get(value.getTeachingClassId()))
                    .setTeachingClassWeeks(teachingClassWeekMap.get(value.getTeachingClassId()))
                    .setTeachingClassList(groupTeaching));
        }
        return list;
    }

    @Override
    public PageInfo<SubClass> getSubClassList(Page<SubClass> page, Integer taskId, String keyword, String baseCollegeId) {
        Page<SubClass> subClassPage = this.lambdaQuery().eq(SubClass::getTaskId, taskId)
                .eq(StrUtil.isNotBlank(baseCollegeId), SubClass::getBaseCollegeId, baseCollegeId)
                .like(StrUtil.isNotBlank(keyword), SubClass::getSubName, keyword).page(page);
        //上课组列表
        Map<String, List<SubClassGroup>> subClassGroupMap = subClassGroupService.lambdaQuery().eq(SubClassGroup::getTaskId, taskId).list()
                .stream().collect(Collectors.groupingBy(SubClassGroup::getUniqueShiftSign));
        for (SubClass subClass : subClassPage.getRecords()) {
            List<SubClassGroup> subClassGroups = subClassGroupMap.get(subClass.getUniqueShiftSign());
            //根据上课组列表获取全部教学班名称
            String teachingClassNames = subClassGroups.stream().map(SubClassGroup::getTeachingClassName).distinct().collect(Collectors.joining(","));
            subClass.setTeachingClassNames(teachingClassNames);

            List<List<SubClassGroup>> subClassGroupDto = new ArrayList<>();
            Map<String, List<SubClassGroup>> map = subClassGroups.stream().collect(Collectors.groupingBy(SubClassGroup::getUniqueGroupSign));
            List<String> uuids = subClassGroups.stream().map(SubClassGroup::getUniqueGroupSign).distinct().collect(Collectors.toList());
            for (String uuid : uuids) {
                subClassGroupDto.add(map.get(uuid));
            }
            subClass.setSubClassGroupList(subClassGroupDto);
            subClass.setSubClassGroups(subClassGroups);
        }
        return PagingUtil.formatPageResult(subClassPage);
    }

    @Override
    public PageInfo<SubClass> getSubTeachingClassHourList(Page<SubClass> page, Integer taskId, String keyword, String baseCollegeId) {
        PageInfo<SubClass> subClassPage = this.getSubClassList(page, taskId, keyword, baseCollegeId);
        List<String> uniqueShiftSigns = subClassPage.getList().stream().map(SubClass::getUniqueShiftSign).distinct().collect(Collectors.toList());
        if (CollUtil.isNotEmpty(uniqueShiftSigns)) {
            //拿到对应教学班 并根据教学班名、授课类型分组
            List<TeachingClassHourVo> teachingClassHour = teachingClassMapper.getTeachingClassHourVo(page, taskId, null, null, null, null, null, uniqueShiftSigns, null, null).getRecords();
            List<Long> teachingIds = teachingClassHour.stream().map(TeachingClassHourVo::getTeachingClassId).collect(Collectors.toList());
            Map<String, List<TeacherDto>> teacherMap = teacherService.getTeacherByTeachingClassIds(teachingIds).stream().collect(Collectors.groupingBy(o -> o.getTeachingClassId() + "-" + o.getHourType()));
            teachingClassHour.forEach(a -> a.setTeachers(teacherMap.get(a.getTeachingClassId() + "-" + a.getHourType())));

            Map<String, List<TeachingClassHourVo>> teachingClassHourMap = teachingClassHour.stream().collect(Collectors.groupingBy(o -> o.getTeachingClassName() + "-" + o.getHourType()));
            //对上课组进行赋值
            for (SubClass subClass : subClassPage.getList()) {
                for (SubClassGroup subClassGroup : subClass.getSubClassGroups()) {
                    Optional<TeachingClassHourVo> first = teachingClassHourMap.get(subClassGroup.getTeachingClassName() + "-" + subClassGroup.getHourType()).stream().findFirst();
                    if (first.isPresent()) {
                        TeachingClassHourVo teachingClassHourVo = BeanUtil.copyProperties(first.get(), TeachingClassHourVo.class);
                        teachingClassHourVo.setWeekNum(subClassGroup.getWeekNum());
                        teachingClassHourVo.setConnectNumber(1);
                        teachingClassHourVo.setConnectSection(1);

                        subClassGroup.setTeachingClassHourVo(teachingClassHourVo);
                    }
                }
            }
        }
        return subClassPage;
    }

    @Override
    public List<SubClassGroup> convertSubClassGroup(List<TeachingClass> teachingClasses) {
        List<SubClassGroup> subClassGroups = new ArrayList<>();
        //将教学班拆成单个排课单元
        for (TeachingClass teachingClass : teachingClasses) {
            for (TeachingClassWeek teachingClassWeek : teachingClass.getTeachingClassWeeks()) {
                String teacherIds = teachingClass.getTeachingClassTeachers().stream()
                        .filter(a -> a.getHourType().equals(teachingClassWeek.getHourType()))
                        .map(TeachingClassTeacher::getTeacherId).toString();
                for (int i = 0; i < teachingClassWeek.getWeekNum(); i++) {
                    subClassGroups.add(new SubClassGroup()
                            .setTaskId(teachingClass.getTaskId())
                            .setUniqueShiftSign(teachingClass.getUniqueShiftSign())
                            .setWeekNum(1)
                            .setHourType(teachingClassWeek.getHourType().toString())
                            .setTeachingClassId(teachingClass.getTeachingClassId())
                            .setTeachingClassName(teachingClass.getTeachingClassName())
                            .setIsSingle(teachingClass.getIsSingle())
                            .setCourseTeacherIds(teachingClass.getCourseId() + teacherIds));
                }
            }
        }
        return subClassGroups;
    }


    /**
     * 校验生成的教学班
     *
     * @param teachingClasses
     */
    public void checkTeachingClass(List<TeachingClass> teachingClasses) {
        //按照奇偶进行分组
        Map<Integer, List<TeachingClass>> isSingleMap = teachingClasses.stream().collect(Collectors.groupingBy(TeachingClass::getIsSingle));
        //奇数
        List<TeachingClass> oddTeachingClasses = isSingleMap.get(1);
        //偶数
        List<TeachingClass> evenTeachingClasses = isSingleMap.get(2);
        if (oddTeachingClasses.size() != evenTeachingClasses.size()) {
            throw new BizException("奇偶教学班数量不一致");
        }

        //满足最大周学时大于等于其他周学时之和
        // 获取每个TeachingClass的周学时总和
        int[] weekSums = oddTeachingClasses.stream()
                .mapToInt(a -> a.getTeachingClassWeeks().stream().mapToInt(TeachingClassWeek::getWeekNum).sum())
                .toArray();
        // 找到最大的周学时数
        int max = IntStream.of(weekSums).max().orElse(0);
        // 计算其他周学时数的总和
        int sumExceptMax = IntStream.of(weekSums).sum() - max;
        // 检查条件是否满足
        if (sumExceptMax < max) {
            throw new BizException("不满足最大周学时大于等于其他周学时之和");
        }
    }

    /**
     * 格式化保存数据，将拆班课程教学班列表，格式化保存到拆班课程对象
     *
     * @param phyClassUnitList 指定行政班，拆班的教学班列表
     * @return
     */
    public LinkedList<SplitSubClass> getSplitCourseList(List<SubClassGroup> phyClassUnitList) {
        //将指定行政班的拆班教学班，按照课程进行分组
        Map<String, LinkedList<SubClassGroup>> phyUnitMap = phyClassUnitList.stream()
                .collect(Collectors.groupingBy((SubClassGroup::getCourseTeacherIds), Collectors.toCollection(LinkedList::new)));
        //定义返回列表
        LinkedList<SplitSubClass> retList = new LinkedList<>();
        //遍历map，将每个课程拆出来的行政班，按照单班和双班的形式，存入SplitCourse
        for (Map.Entry<String, LinkedList<SubClassGroup>> entry : phyUnitMap.entrySet()) {
            //定义存储奇数教学班的列表
            LinkedList<SubClassGroup> oddList = new LinkedList<>();
            //定义存储偶数教学班的列表
            LinkedList<SubClassGroup> evenList = new LinkedList<>();
            for (SubClassGroup teachingClassUnit : entry.getValue()) {
                //奇数
                if (teachingClassUnit.getIsSingle().equals(1)) {
                    oddList.add(teachingClassUnit);
                } else {//偶数
                    evenList.add(teachingClassUnit);
                }
            }
            //生成分班课程对象
            SplitSubClass splitCourse = new SplitSubClass(entry.getKey(), oddList, evenList);
            //将分班课程对象，加入返回值列表
            retList.add(splitCourse);
        }
        return retList;
    }

    /**
     * 开始进行分组配对
     *
     * @param evenCourse 分配偶数教学班配对的课程
     * @param oddCourse  分配奇数教学班配对的课程
     */
    public void startGroup(SplitSubClass evenCourse,
                           SplitSubClass oddCourse,
                           LinkedList<SubClassGroup> groupedList) {
        //生成一个UUID，作为分组id
        String splitClassGroupId = UUID.randomUUID().toString();
        //将最大课程的偶数教学班排课单元列表中的第一个元素取出来
        SubClassGroup evenUnit = evenCourse.getEvenClassList().getFirst();
        //将其他课程的奇数教学班排课单元列表中的第一个元素取出来
        SubClassGroup oddUnit = oddCourse.getOddClassList().getFirst();

        String groupName = evenUnit.getCourseName() + oddUnit.getCourseName() + "上课组" + GROUP_NUM;
        GROUP_NUM++;

        //设置配对的分组id
        evenUnit.setUniqueGroupSign(splitClassGroupId);
        evenUnit.setGroupName(groupName);
        //将配对的教学班排课单元对象加入返回列表
        groupedList.add(evenUnit);
        //将配对完成的教学班排课单元对象，从最大的课程的偶数教学班排课单元列表中移除
        evenCourse.getEvenClassList().remove(evenUnit);

        //设置配对的分组id
        oddUnit.setUniqueGroupSign(splitClassGroupId);
        oddUnit.setGroupName(groupName);
        //将配对的教学班排课单元对象加入返回列表
        groupedList.add(oddUnit);
        //将配对完成的教学班排课单元对象，从课程的奇数数教学班排课单元列表中移除
        oddCourse.getOddClassList().remove(oddUnit);
    }

//    @Override
//    public Boolean removeSubClass(List<String> uniqueShiftSigns) {
//        //删除分组
//        this.lambdaUpdate().in(SubClass::getUniqueShiftSign, uniqueShiftSigns).remove();
//        //删除教学班
//        List<TeachingClass> subTeachingClassList = teachingClassService.lambdaQuery()
//                .in(TeachingClass::getUniqueShiftSign, uniqueShiftSigns).select(TeachingClass::getTeachingClassId).list();
//        teachingClassService.deleteClass(subTeachingClassList.stream().map(TeachingClass::getTeachingClassId).collect(Collectors.toList()));
//        //删除上课组
//        subClassGroupService.lambdaUpdate().in(SubClassGroup::getUniqueShiftSign, uniqueShiftSigns).remove();
//
//        return true;
//    }

    @Override
    public List<Map<String, Object>> phyClassList(Integer taskId, String collegeId, String gradeId) {
        List<Map<String, Object>> result = new ArrayList<>();
        List<Student> studentList = studentService.lambdaQuery()
                .eq(Student::getTaskId, taskId)
                .eq(StringUtils.isNotBlank(gradeId), Student::getGradeId, gradeId)
                .eq(StringUtils.isNotBlank(collegeId), Student::getBaseCollegeId, collegeId)
                .isNotNull(Student::getClassId)
                .list();
        List<String> classIds = studentList.stream().map(Student::getClassId).distinct().collect(Collectors.toList());
        for (String classId : classIds) {
            Student student = studentList.stream().filter(a -> a.getClassId().equals(classId)).findFirst().get();
            Map<String, Object> map = new HashMap<>();
            map.put("phyClassId", classId);
            map.put("phyClassName", student.getClassName());
            map.put("gradeId", student.getGradeId());
            map.put("gradeName", student.getGradeName());
            map.put("baseCollegeId", student.getBaseCollegeId());
            map.put("collegeName", student.getCollegeName());
            result.add(map);
        }
        return result;
    }

    @Override
    @Transactional
    public List<TeachingClass> updatePhyClassList(Integer taskId, String classId, String uniqueShiftSign, List<Long> courseIds) {
        if (CollUtil.isNotEmpty(courseIds) && courseIds.size() == 1) {
            throw new BizException("分组上课最少选择两门课程！");
        }
        if (StringUtils.isNotBlank(uniqueShiftSign)) {
            //编辑-修改，先删除原来生成的教学班
            teachingClassService.lambdaUpdate().eq(TeachingClass::getUniqueShiftSign, uniqueShiftSign).remove();
        }
        List<Course> courseList = courseService.lambdaQuery().eq(Course::getTaskId, taskId).in(Course::getCourseId, courseIds).list();
        List<CourseWeek> courseWeekList = courseWeekService.lambdaQuery().eq(CourseWeek::getTaskId, taskId).in(CourseWeek::getCourseId, courseIds).list();
        if (CollUtil.isNotEmpty(courseIds)) {
            //周学时校验
            if (courseIds.size() == 2) {
                List<CourseWeek> first = courseWeekList.stream().filter(a -> a.getCourseId().equals(courseIds.get(0))).collect(Collectors.toList());
                List<CourseWeek> second = courseWeekList.stream().filter(a -> a.getCourseId().equals(courseIds.get(1))).collect(Collectors.toList());
                Integer sum1 = first.stream().map(CourseWeek::getWeekNum).reduce(Integer::sum).get();
                Integer sum2 = second.stream().map(CourseWeek::getWeekNum).reduce(Integer::sum).get();
                if (!sum1.equals(sum2)) {
                    throw new BizException("课程周学时不一致");
                }
            } else {
                List<Integer> weekNums = new ArrayList<>();
                for (Long item : courseIds) {
                    List<CourseWeek> first = courseWeekList.stream().filter(a -> a.getCourseId().equals(item)).collect(Collectors.toList());
                    Integer sum1 = first.stream().map(CourseWeek::getWeekNum).reduce(Integer::sum).get();
                    weekNums.add(sum1);
                }
                Integer max = weekNums.stream().max(Integer::compareTo).orElse(0);
                weekNums.remove(max);
                Integer sum = weekNums.stream().reduce(Integer::sum).orElse(0);
                if (max > sum) {
                    throw new BizException("需满足：周学时最大课程的周学时，小于等于其他课程周学时的总和");
                }
            }
        }
        //分组上课的教学班生成后，原来生成的教学班信息将自动删除掉
        List<Long> teachingClassIds = teachingClassService.lambdaQuery()
                .eq(TeachingClass::getTaskId, taskId)
                .in(TeachingClass::getCourseId, courseIds).list()
                .stream().map(TeachingClass::getTeachingClassId).collect(Collectors.toList());
        teachingClassService.deleteClass(teachingClassIds);
        //单双班学生
        List<Student> studentList = studentService.lambdaQuery().eq(Student::getClassId, classId).list();
        List<Student> singleStu = new ArrayList<>();
        List<Student> doubleStu = new ArrayList<>();
        studentList.forEach(stu -> {
            int last = Integer.parseInt(stu.getBaseStudentId().substring(stu.getBaseStudentId().length() - 1));
            if (last % 2 == 0) {
                doubleStu.add(stu);
            } else {
                singleStu.add(stu);
            }
        });
        Student student = studentList.get(0);
        MajorGrade majorGrade = majorGradeService.lambdaQuery().eq(MajorGrade::getGradeId, student.getGradeId())
                .eq(MajorGrade::getBaseMajorId, student.getMajorId())
                .eq(MajorGrade::getBaseCollegeId, student.getBaseCollegeId())
                .eq(MajorGrade::getTaskId, taskId).one();
        if (majorGrade == null) {
            throw new BizException("【" + student.getCollegeName() + student.getGradeName() + student.getMajorName() + "】，不存在该学院年级专业");
        }
        List<TeachingClass> classList = new ArrayList<>();
        //教学班对应学生
        List<TeachingClassStudent> teachingClassStudentList = new ArrayList<>();
        UUID uuid = UUID.randomUUID();
        for (Course course : courseList) {
            TeachingClass singleClass = new TeachingClass()
                    .setTaskId(taskId)
                    .setTeachingClassName(course.getCourseName() + "(单)")
                    .setCourseId(course.getCourseId())
                    .setCourseName(course.getCourseName())
                    .setStudyNature(course.getCourseNature())
                    .setMajorProp(course.getMajorProp())
                    .setClassNum(studentList.size() / 2)
                    .setBaseMajorId(student.getMajorId())
                    .setMajorName(student.getMajorName())
                    .setBaseCollegeId(student.getBaseCollegeId())
                    .setCollegeName(student.getCollegeName())
                    .setGradeId(student.getGradeId())
                    .setGradeName(student.getGradeName())
                    .setTeachingClassType(0)
                    .setFlag(1)
                    .setCampusId(majorGrade.getCampusId())
                    .setCampusName(majorGrade.getCampusName())
                    .setUniqueShiftSign(uuid.toString())
                    .setIsSingle(1).setToClass(classId);
            teachingClassService.save(singleClass);
            classList.add(singleClass);
            //单班教学班学生
            singleStu.forEach(a -> {
                teachingClassStudentList.add(new TeachingClassStudent()
                        .setFlag(1)
                        .setTeachingClassId(singleClass.getTeachingClassId())
                        .setCourseId(course.getCourseId())
                        .setStudentId(a.getStudentId()));
            });

            TeachingClass doubleClass = new TeachingClass()
                    .setTaskId(taskId)
                    .setTeachingClassName(course.getCourseName() + "(双)")
                    .setCourseId(course.getCourseId())
                    .setCourseName(course.getCourseName())
                    .setCourseName(course.getCourseName())
                    .setStudyNature(course.getCourseNature())
                    .setClassNum(studentList.size() / 2)
                    .setBaseMajorId(student.getMajorId())
                    .setMajorName(student.getMajorName())
                    .setBaseCollegeId(student.getBaseCollegeId())
                    .setCollegeName(student.getCollegeName())
                    .setGradeId(student.getGradeId())
                    .setGradeName(student.getGradeName())
                    .setTeachingClassType(0)
                    .setFlag(1)
                    .setCampusId(majorGrade.getCampusId())
                    .setCampusName(majorGrade.getCampusName())
                    .setUniqueShiftSign(uuid.toString())
                    .setIsSingle(2).setToClass(classId);
            teachingClassService.save(doubleClass);
            classList.add(doubleClass);
            //双班教学班学生
            doubleStu.forEach(a -> {
                teachingClassStudentList.add(new TeachingClassStudent()
                        .setFlag(1)
                        .setTeachingClassId(doubleClass.getTeachingClassId())
                        .setCourseId(course.getCourseId())
                        .setStudentId(a.getStudentId()));
            });
        }

        List<TeachingClassWeek> allTeachingClassWeeks = classImplService.initTeachingClassWeek(classList);
        Consumer<List<TeachingClassWeek>> teachingClassWeekConsumer = o -> teachingClassWeekMapper.addBatch(o);
        BatchInsert.batchSplitInsert(allTeachingClassWeeks, teachingClassWeekConsumer);

        //批量插入教学班学生，大数据批量插入
        Consumer<List<TeachingClassStudent>> studentConsumer = o -> teachingClassStudentMapper.addBatch(o);
        BatchInsert.batchSplitInsert(teachingClassStudentList, studentConsumer);

        for (TeachingClass item : classList) {
            List<CourseWeek> weekList = courseWeekList.stream().filter(a -> a.getCourseId().equals(item.getCourseId())).collect(Collectors.toList());
            Integer weekNum = 0;
            for (CourseWeek week : weekList) {
                weekNum += week.getWeekNum();
            }
            item.setWeekNum(weekNum);
        }
        return classList;
    }

    @Override
    public List<TeachingClass> getSubTeachingClass(String uniqueShiftSign) {
        List<TeachingClass> teachingClassList = teachingClassService.lambdaQuery()
                .eq(TeachingClass::getUniqueShiftSign, uniqueShiftSign).list();
        List<Long> ids = teachingClassList.stream().map(TeachingClass::getTeachingClassId).collect(Collectors.toList());
        //填充教师
        List<Teacher> teachers = teacherService.lambdaQuery().list();
        Map<Long, List<TeachingClassTeacher>> teacherMap = teachingClassTeacherService.lambdaQuery()
                .in(TeachingClassTeacher::getTeachingClassId, ids).list()
                .stream().collect(Collectors.groupingBy(TeachingClassTeacher::getTeachingClassId));
        //填充参数
        Map<Long, List<TeachingClassWeek>> weekMap = teachingClassWeekService.lambdaQuery()
                .in(TeachingClassWeek::getTeachingClassId, ids).list()
                .stream().collect(Collectors.groupingBy(TeachingClassWeek::getTeachingClassId));
        for (TeachingClass teachingClass : teachingClassList) {
            teachingClass.setTeachingClassTeachers(teacherMap.get(teachingClass.getTeachingClassId()));
            teachingClass.setTeachingClassWeeks(weekMap.get(teachingClass.getTeachingClassId()));
            if (teachingClass.getTeachingClassTeachers() != null) {
                for (TeachingClassTeacher item : teachingClass.getTeachingClassTeachers()) {
                    try {
                        Teacher teacher = teachers.stream().filter(a -> a.getTeacherId().equals(item.getTeacherId())).findFirst().get();
                        item.setIdentity(teacher.getIdentity());
                        item.setTeacherName(teacher.getTeacherName());
                        item.setImageUrl(teacher.getImageUrl());
                        item.setBaseTeacherId(teacher.getBaseTeacherId());
                    } catch (Exception e) {
                        throw new BizException("教师信息不存在或被删除");
                    }
                }
            }
        }
        List<CourseWeek> courseWeekList = courseWeekService.lambdaQuery().list();
        for (TeachingClass item : teachingClassList) {
            List<CourseWeek> weekList = courseWeekList.stream().filter(a -> a.getCourseId().equals(item.getCourseId())).collect(Collectors.toList());
            Integer weekNum = 0;
            for (CourseWeek week : weekList) {
                weekNum += week.getWeekNum();
            }
            item.setWeekNum(weekNum);
        }
        return teachingClassList;
    }

    @Override
    public List<Course> getGroupCourse(Integer taskId, String classId) {
        List<Student> studentList = studentService.lambdaQuery().eq(Student::getTaskId, taskId).eq(Student::getClassId, classId).list();
        List<String> baseStuIds = studentList.stream().map(Student::getBaseStudentId).collect(Collectors.toList());
        List<PlanTeachingStudent> planStudents = planTeachingStudentService.lambdaQuery().eq(PlanTeachingStudent::getTaskId, taskId).in(PlanTeachingStudent::getBaseStudentId, baseStuIds).list();
        List<String> basePlanIds = planStudents.stream().map(PlanTeachingStudent::getBaseTeachingPlanId).distinct().collect(Collectors.toList());
        if (CollUtil.isEmpty(basePlanIds)) {
            throw new BizException("该班级的学生未设置培养计划，请前往基础教务确认！");
        }
        //求交集
        List<String> courseList = planTeachingCourseService.lambdaQuery()
                .eq(PlanTeachingCourse::getBaseTeachingPlanId, basePlanIds.get(0))
                .list()
                .stream().map(PlanTeachingCourse::getBaseCourseId).collect(Collectors.toList());
        if (basePlanIds.size() > 1) {
            List<String> courseList2 = planTeachingCourseService.lambdaQuery()
                    .eq(PlanTeachingCourse::getBaseTeachingPlanId, basePlanIds.get(1))
                    .list()
                    .stream().map(PlanTeachingCourse::getBaseCourseId).collect(Collectors.toList());
            courseList = courseList.stream().filter(courseList2::contains).collect(Collectors.toList());
            for (int i = 1; i < basePlanIds.size(); i++) {
                List<String> courseList3 = planTeachingCourseService.lambdaQuery()
                        .eq(PlanTeachingCourse::getBaseTeachingPlanId, basePlanIds.get(i))
                        .list()
                        .stream().map(PlanTeachingCourse::getBaseCourseId).collect(Collectors.toList());
                courseList = courseList.stream().filter(courseList3::contains).collect(Collectors.toList());
            }
        }
        List<Course> courses = courseService.lambdaQuery().eq(Course::getTaskId, taskId).in(CollUtil.isNotEmpty(courseList), Course::getBaseCourseId, courseList).list();
        List<CourseWeek> weekList = courseWeekService.lambdaQuery().eq(CourseWeek::getTaskId, taskId).list();
        List<Course> removeCourse = new ArrayList<>();
        for (Course item : courses) {
            item.setTotalHour(item.getComputerHour() + item.getLectureHour() + item.getOtherHour() + item.getExperimentalHour());
            Optional<CourseWeek> week = weekList.stream().filter(a -> a.getCourseId().equals(item.getCourseId())).findFirst();
            List<CourseWeek> weeks = weekList.stream().filter(a -> a.getCourseId().equals(item.getCourseId())).collect(Collectors.toList());
            if (CollUtil.isNotEmpty(weeks)) {
                //课程参数空的则删除，不为空但是周学时不存在的也删除
                boolean todoFlag = true;
                for (CourseWeek courseWeek : weeks) {
                    if (courseWeek.getWeekNum() == null) {
                        todoFlag = false;
                    }
                }
                if (todoFlag) {
                    Integer weekNumForSub = weeks.stream().mapToInt(CourseWeek::getWeekNum).sum();
                    item.setWeekNumForSub(weekNumForSub);
                } else {
                    removeCourse.add(item);
                }
            } else {
                removeCourse.add(item);
            }
//            if (week.isPresent()) {
//                if (week.get().getWeekNum() == null) {
//                    removeCourse.add(item);
//                } else {
//                    item.setWeekNumForSub(weekNumForSub);
//                }
//            } else {
//                removeCourse.add(item);
//            }
        }
        courses.removeAll(removeCourse);
        return courses;
    }

//    @Override
//    public List<SubClassGroup> addClassGroup(Integer taskId, List<SubClassGroup> param) {
//        subClassGroupService.saveBatch(param);
//        return subClassGroupService.lambdaQuery()
//                .eq(SubClassGroup::getTaskId, taskId)
//                .in(SubClassGroup::getId, param.stream().map(SubClassGroup::getId).collect(Collectors.toList()))
//                .list();
//    }

    @Override
    public Boolean removeClassGroup(Integer taskId, String uniqueShiftSign) {
        subClassGroupService.lambdaUpdate()
                .eq(SubClassGroup::getTaskId, taskId)
                .in(SubClassGroup::getUniqueShiftSign, uniqueShiftSign)
                .remove();
        subClassGroupTempService.lambdaUpdate()
                .eq(SubClassGroupTemp::getTaskId, taskId)
                .in(SubClassGroupTemp::getUniqueShiftSign, uniqueShiftSign)
                .remove();
        return true;
    }

    @Override
    public Boolean removeSubClass(List<String> uniqueShiftSigns) {
        //删除分组
        this.lambdaUpdate().in(SubClass::getUniqueShiftSign, uniqueShiftSigns).remove();
        //删除教学班
        List<TeachingClass> subTeachingClassList = teachingClassService.lambdaQuery()
                .in(TeachingClass::getUniqueShiftSign, uniqueShiftSigns).select(TeachingClass::getTeachingClassId).list();
        teachingClassService.deleteClass(subTeachingClassList.stream().map(TeachingClass::getTeachingClassId).collect(Collectors.toList()));
        //删除上课组
        subClassGroupService.lambdaUpdate().in(SubClassGroup::getUniqueShiftSign, uniqueShiftSigns).remove();
        subClassGroupTempService.lambdaUpdate().in(SubClassGroupTemp::getUniqueShiftSign, uniqueShiftSigns).remove();

        return true;
    }

    @Override
    public Boolean addSubClass(AddSubClassVo addSubClassVo) {
        this.save(addSubClassVo.getSubClass());
//        teachingClassService.addBatchTeachingClass(taskId, addSubClassVo.getTeachingClasses());
        subClassGroupService.saveBatch(addSubClassVo.getSubClassGroups());
        return true;
    }

    @Override
    public LinkedList<SubClassGroup> splitClassGroup(List<TeachingClass> teachingClasses) {
        //定义用来保存已经标记分组的教学班排课单元列表
        LinkedList<SubClassGroup> pairedClass = new LinkedList<>();
        checkTeachingClass(teachingClasses);
        List<SubClassGroup> subClassGroups = convertSubClassGroup(teachingClasses);

        //将拆班教学班列表，格式化保存到SplitCourse对象，方便进行配对
        LinkedList<SplitSubClass> splitCourseList = getSplitCourseList(subClassGroups);
        // 进行分组
        int loopCount = 0;
        // 设置最大循环次数为教学班排课单元列表的数量
        int maxLoopCount = subClassGroups.size();
        while (!splitCourseList.isEmpty() && loopCount < maxLoopCount) {
            loopCount++; // 增加循环计数器

            //获取列表中，教学班数量最大的那个元素
            //即奇数教学班排课列表的大小+偶数列表的大小
            Optional<SplitSubClass> maxObject = splitCourseList.stream()
                    .max(Comparator.comparing(SplitSubClass::getSize));

            //从Optional中获取拆班课程对象
            SplitSubClass maxCourse = maxObject.get();
            //从列表中删除最大的课程
            splitCourseList.remove(maxCourse);
            List<SplitSubClass> coursesToRemove = new ArrayList<>();

            //赋值分组编号默认值
            GROUP_NUM = 1;
            for (SplitSubClass splitCourse : splitCourseList) {
                if (maxCourse.getEvenClassList().isEmpty() || splitCourse.getOddClassList().isEmpty()) {
                    continue;
                }

                //如果教学班数量最多的课程，偶数教学班数量，大于等于奇数教学班数量
                //用最多的这个课程的偶数教学班，去匹配其他教学班的奇数教学班
                if (maxCourse.getEvenClassList().size() >= splitCourse.getOddClassList().size()) {
                    startGroup(maxCourse, splitCourse, pairedClass);
                } else {
                    startGroup(splitCourse, maxCourse, pairedClass);
                }

                //如果这个课程配对完成后，没有需要配对的排课教学班单元了，那么将其从拆班教学班列表中移除
                if (splitCourse.getSize() == 0) {
                    coursesToRemove.add(splitCourse);
                }
            }

            splitCourseList.removeAll(coursesToRemove);

            if (maxCourse.getSize() != 0) {
                splitCourseList.add(maxCourse);
            }
        }
        // 将分组中两个课程一样的分组进行合并?
        return pairedClass;
    }

//    @Override
//    public Boolean deleteGroup(Integer taskId, Long uuid) {
//        this.lambdaUpdate()
//                .eq(SubClass::getUniqueShiftSign, uuid)
//                .remove();
//        subClassGroupService.lambdaUpdate()
//                .eq(SubClassGroup::getUniqueShiftSign, uuid)
//                .remove();
//
//        return true;
//    }

    @Override
    public SubGroupDto groupOddEvenGroup(Integer taskId, String uuid) {
        SubGroupDto result = new SubGroupDto();
        //获取全部分组信息
        List<SubClassGroupTemp> teachingClassSubGroupTemps = subClassGroupTempService.lambdaQuery()
                .eq(SubClassGroupTemp::getTaskId, taskId)
                .eq(SubClassGroupTemp::getUniqueShiftSign, uuid)
                .list();
        List<Long> courseIds = teachingClassSubGroupTemps.stream().map(SubClassGroupTemp::getCourseId).distinct().collect(Collectors.toList());
        //获取对应课程
        List<Course> courseList = new ArrayList<>();
        if (CollUtil.isNotEmpty(courseIds)) {
            courseList = courseService.lambdaQuery()
                    .eq(Course::getTaskId, taskId)
                    .in(Course::getCourseId, courseIds)
                    .list();
        }
        //获取单班
        List<SubClassGroupTemp> singleTeachingClassSubGroupTemp = teachingClassSubGroupTemps.stream()
                .filter(p -> StringUtils.isBlank(p.getUniqueGroupSign()) && p.getIsSingle().equals(1))
                .collect(Collectors.toList());
        List<SubClassGroup> singleGroupList = new ArrayList<>();
        if (CollUtil.isNotEmpty(singleTeachingClassSubGroupTemp)) {
            List<Course> finalCourseList = courseList;
            singleTeachingClassSubGroupTemp.forEach(o -> {
                SubClassGroup singleGroup = new SubClassGroup();
                singleGroup.setId(o.getId());
                Course course = finalCourseList.stream().filter(p -> p.getCourseId().equals(o.getCourseId())).findFirst().orElse(null);
                if (ObjUtil.isNotNull(course)) {
                    singleGroup.setCourseId(course.getCourseId());
                    singleGroup.setCourseName(course.getCourseName());
                }
                singleGroup.setHourType(o.getHourType());
                singleGroup.setIsSingle(o.getIsSingle());
                singleGroup.setTeachingClassId(o.getTeachingClassId());
                singleGroup.setTeachingClassName(o.getTeachingClassName());
                singleGroup.setWeekNum(1);
                singleGroupList.add(singleGroup);
            });
        }
        //获取双班
        List<SubClassGroupTemp> doubleTeachingClassSubGroupTemp = teachingClassSubGroupTemps.stream().filter(p -> StringUtils.isBlank(p.getUniqueGroupSign())
                && p.getIsSingle().equals(2)).collect(Collectors.toList());
        List<SubClassGroup> doubleGroupList = new ArrayList<>();
        if (CollUtil.isNotEmpty(doubleTeachingClassSubGroupTemp)) {
            List<Course> finalCourseList = courseList;
            doubleTeachingClassSubGroupTemp.forEach(o -> {
                SubClassGroup doubleGroup = new SubClassGroup();
                doubleGroup.setId(o.getId());
                Course course = finalCourseList.stream().filter(p -> p.getCourseId().equals(o.getCourseId()))
                        .findFirst().orElse(null);
                if (ObjUtil.isNotNull(course)) {
                    doubleGroup.setCourseId(course.getCourseId());
                    doubleGroup.setCourseName(course.getCourseName());
                }
                doubleGroup.setHourType(o.getHourType());
                doubleGroup.setIsSingle(o.getIsSingle());
                doubleGroup.setTeachingClassId(o.getTeachingClassId());
                doubleGroup.setTeachingClassName(o.getTeachingClassName());
                doubleGroup.setWeekNum(1);
                doubleGroupList.add(doubleGroup);
            });
        }
        //获取已经进行课程列表
        List<SubClassGroupTemp> teachingClassSubGroupTempList =
                teachingClassSubGroupTemps.stream().filter(p -> StringUtils.isNotBlank(p.getUniqueGroupSign()))
                        .collect(Collectors.toList());

        List<SubGroupVo> subGroupVos = new ArrayList<>();
        Map<String, List<SubClassGroupTemp>> groupMap = teachingClassSubGroupTempList.stream().collect(Collectors.groupingBy(SubClassGroupTemp::getUniqueGroupSign));
        groupMap.forEach((key, value) -> {
            SubClassGroupTemp teachingClassSubGroupTemp = value.get(0);
            SubGroupVo subGroupDto = new SubGroupVo();
            subGroupDto.setUniqueGroupSign(teachingClassSubGroupTemp.getUniqueGroupSign());
            subGroupDto.setGroupName(teachingClassSubGroupTemp.getGroupName());
            subGroupDto.setSubGroupTemps(value);
            subGroupDto.setWeekNum(teachingClassSubGroupTemp.getWeekNum());
            subGroupVos.add(subGroupDto);
        });

        result.setSingleGroupList(singleGroupList);
        result.setDoubleGroupList(doubleGroupList);
        result.setSubGroupVoList(subGroupVos);
        return result;

    }

    @Override
    public String creatManualGroup(Integer taskId, String uuid) {
        List<SubClassGroupTemp> teachingClassSubGroups = new ArrayList<>();

        List<SubClassGroupTemp> list = subClassGroupTempService.lambdaQuery()
                .eq(SubClassGroupTemp::getTaskId, taskId)
                .eq(SubClassGroupTemp::getUniqueShiftSign, uuid)
                .list();

        if (CollUtil.isNotEmpty(list)) {
            return "手动分组已生成";
        }

        List<TeachingClass> teachingClassList = teachingClassService.lambdaQuery()
                .eq(TeachingClass::getTaskId, taskId)
                .eq(TeachingClass::getUniqueShiftSign, uuid)
                .list();

        List<Long> teachingClassIds = teachingClassList.stream().map(TeachingClass::getTeachingClassId).collect(Collectors.toList());

        if (CollUtil.isNotEmpty(teachingClassIds)) {
            List<TeachingClassWeek> teachingClassWeeks = teachingClassWeekService.lambdaQuery()
                    .in(TeachingClassWeek::getTeachingClassId, teachingClassIds)
                    .list();

            if (CollUtil.isNotEmpty(teachingClassWeeks)) {
                Map<Long, List<TeachingClassWeek>> teachingClasssMap = teachingClassWeeks.stream().collect(Collectors.groupingBy(TeachingClassWeek::getTeachingClassId));
                teachingClasssMap.forEach((key, value) -> {
                    value.forEach(o -> {
                        Integer weekNum = o.getWeekNum();
                        for (int i = 0; i < weekNum; i++) {
                            SubClassGroupTemp teachingClassSubGroup = new SubClassGroupTemp();
                            teachingClassSubGroup.setTaskId(taskId);
                            teachingClassSubGroup.setWeekNum(1);
                            TeachingClass teachingClass = teachingClassList.stream().filter(p -> p.getTeachingClassId().equals(key)).findFirst().orElse(null);
                            if (ObjUtil.isNotNull(teachingClass)) {
                                teachingClassSubGroup.setTeachingClassId(teachingClass.getTeachingClassId());
                                teachingClassSubGroup.setTeachingClassName(teachingClass.getTeachingClassName());
                                teachingClassSubGroup.setCourseId(teachingClass.getCourseId());
                                teachingClassSubGroup.setHourType(String.valueOf(o.getHourType()));
                                teachingClassSubGroup.setWeekNum(1);
                                teachingClassSubGroup.setUniqueShiftSign(teachingClass.getUniqueShiftSign());
                                teachingClassSubGroup.setIsSingle(teachingClass.getIsSingle());
                                teachingClassSubGroups.add(teachingClassSubGroup);
                            }
                        }
                    });
                });
            }
        }

        subClassGroupTempService.saveBatch(teachingClassSubGroups);
        return "手动生成分组成功";
    }

    @Override
    public Boolean addGroupToCourse(Integer taskId, String subId, List<Integer> ids) {
        List<SubClassGroupTemp> teachingClassSubGroupTemps = subClassGroupTempService.lambdaQuery()
                .eq(SubClassGroupTemp::getTaskId, taskId)
                .eq(SubClassGroupTemp::getUniqueShiftSign, subId).list();
        List<Course> courseList = courseService.lambdaQuery().eq(Course::getTaskId, taskId).list();
        if (CollUtil.isNotEmpty(teachingClassSubGroupTemps)) {
            List<SubClassGroupTemp> teachingClassSubGroupTemps1 = teachingClassSubGroupTemps.stream().filter(p -> ids.contains(p.getId())).collect(Collectors.toList());
            //获取传入单班
            List<SubClassGroupTemp> singleTeachingClassSubGroup = teachingClassSubGroupTemps1.stream().filter(p -> p.getIsSingle().equals(1)).collect(Collectors.toList());
            List<Long> singleCourseId = singleTeachingClassSubGroup.stream().map(SubClassGroupTemp::getCourseId).distinct().collect(Collectors.toList());
            //获取传入双班
            List<SubClassGroupTemp> doubleTeachingClassSubGroup = teachingClassSubGroupTemps1.stream().filter(p -> p.getIsSingle().equals(2)).collect(Collectors.toList());
            List<Long> doubleCourseId = doubleTeachingClassSubGroup.stream().map(SubClassGroupTemp::getCourseId).distinct().collect(Collectors.toList());

            List<SubClassGroupTemp> subGroup = new ArrayList<>(teachingClassSubGroupTemps);
            if (CollUtil.isEmpty(singleTeachingClassSubGroup) || CollUtil.isEmpty(doubleTeachingClassSubGroup)) {
                throw new BizException("请至少选择一个单班和一个双班");
            }
            if (singleTeachingClassSubGroup.size() != doubleTeachingClassSubGroup.size()) {
                throw new BizException("单班选择数量应和双班选择数量相同");
            }

            if (CollUtil.isNotEmpty(singleCourseId) && CollUtil.isNotEmpty(doubleCourseId)) {
                if (singleCourseId.size() != 1 || doubleCourseId.size() != 1) {
                    throw new BizException("如果需要进行复选操作,单班教学班和双班教学班只能分别选择同一门课程");
                } else {
                    Long course1 = singleCourseId.get(0);
                    Long course2 = doubleCourseId.get(0);
                    if (course1.equals(course2)) {
                        throw new BizException("单班教学班列表和双班教学班列表不可以选择相同的课程");
                    }
                }
            }
            teachingClassSubGroupTemps.removeAll(teachingClassSubGroupTemps1);
            List<SubClassGroupTemp> teachingClassSubGroupTemps2 = new ArrayList<>(teachingClassSubGroupTemps);
            if (CollUtil.isNotEmpty(teachingClassSubGroupTemps2)) {
                Map<Long, List<SubClassGroupTemp>> courseMap = teachingClassSubGroupTemps2.stream().collect(Collectors.groupingBy(SubClassGroupTemp::getCourseId));
                List<Integer> weekNum = new ArrayList<>();
                courseMap.forEach((key, value) -> {
                    weekNum.add(value.size());
                });
                boolean flag = isDistribution(weekNum);
                if (!flag) {
                    throw new BizException("如果这样分组可能会导致接下来的分组进行不下去，请核对后在进行操作");
                }
            }

            Map<Integer, List<SubClassGroupTemp>> subGroupMap = subGroup.stream().collect(Collectors.groupingBy(SubClassGroupTemp::getId));
            List<SubClassGroupTemp> teachingClassSubGroupTemps3 = new ArrayList<>();
            String uuid = UUID.randomUUID().toString();
            //生成对应的分组
            SubClassGroupTemp singleG = singleTeachingClassSubGroup.get(0);
            SubClassGroupTemp doubleG = doubleTeachingClassSubGroup.get(0);

            List<Long> courseId = new ArrayList<>();
            courseId.add(singleG.getCourseId());
            courseId.add(doubleG.getCourseId());
            List<Course> courses = courseList.stream().filter(p -> courseId.contains(p.getCourseId())).collect(Collectors.toList());

            if (CollUtil.isEmpty(courses) || courses.size() != 2) {
                throw new BizException("单双课程不存在");
            }

            List<SubClassGroupTemp> countData = subClassGroupTempService.lambdaQuery()
                    .eq(SubClassGroupTemp::getTaskId, taskId)
                    .eq(SubClassGroupTemp::getUniqueShiftSign, subId)
                    .isNotNull(SubClassGroupTemp::getUniqueGroupSign)
                    .list();

            //单班教学班列表
            SubClassGroupTemp temp1 = new SubClassGroupTemp();
            temp1.setTaskId(taskId);
            temp1.setUniqueGroupSign(uuid);
            temp1.setGroupName(courses.get(0).getCourseName() + courses.get(1).getCourseName() + "上课组" + (countData.size() + 1));
            temp1.setWeekNum(singleTeachingClassSubGroup.size());
            temp1.setTeachingClassId(singleG.getTeachingClassId());
            temp1.setTeachingClassName(singleG.getTeachingClassName());
            temp1.setCourseId(singleG.getCourseId());
            String hourTypeId = singleTeachingClassSubGroup.stream().map(SubClassGroupTemp::getHourType).collect(Collectors.joining(","));
            temp1.setHourType(hourTypeId);
            temp1.setUniqueShiftSign(subId);
            temp1.setIsSingle(singleG.getIsSingle());
            String singleIds = singleTeachingClassSubGroup.stream().map(SubClassGroupTemp::getId).map(String::valueOf).collect(Collectors.joining(","));
            teachingClassSubGroupTemps3.add(temp1);

            SubClassGroupTemp temp2 = new SubClassGroupTemp();
            temp2.setTaskId(taskId);
            temp2.setUniqueGroupSign(uuid);
            temp2.setGroupName(courses.get(0).getCourseName() + courses.get(1).getCourseName() + "上课组" + (countData.size() + 1));
            temp2.setWeekNum(singleTeachingClassSubGroup.size());
            temp2.setTeachingClassId(doubleG.getTeachingClassId());
            temp2.setTeachingClassName(doubleG.getTeachingClassName());
            temp2.setCourseId(doubleG.getCourseId());
            String doubleHourTypeId = doubleTeachingClassSubGroup.stream().map(SubClassGroupTemp::getHourType).collect(Collectors.joining(","));
            temp2.setHourType(doubleHourTypeId);
            temp2.setUniqueShiftSign(subId);
            temp2.setIsSingle(doubleG.getIsSingle());
            String doubleIds = doubleTeachingClassSubGroup.stream().map(SubClassGroupTemp::getId).map(String::valueOf).collect(Collectors.joining(","));
            teachingClassSubGroupTemps3.add(temp2);

            subClassGroupTempService.lambdaUpdate()
                    .in(SubClassGroupTemp::getId, ids)
                    .remove();
            subClassGroupTempService.saveOrUpdateBatch(teachingClassSubGroupTemps3);
        }
        return true;
    }

    private boolean isDistribution(List<Integer> weekNum) {
        //获取最大值
        int max = 0;
        for (Integer num : weekNum) {
            if (num >= max) {
                max = num;
            }
        }
        int sum = weekNum.stream().mapToInt(Integer::intValue).sum();
        sum = sum - max;
        if (max > sum) {
            return false;
        }
        return true;
    }

    @Override
    public Boolean recoveryCourseGroup(Integer taskId, String uuid, List<Integer> ids) {
        List<SubClassGroupTemp> teachingClassSubGroupTemps = subClassGroupTempService.lambdaQuery()
                .eq(SubClassGroupTemp::getTaskId, taskId)
                .eq(SubClassGroupTemp::getUniqueShiftSign, uuid)
                .in(SubClassGroupTemp::getId, ids)
                .list();

        subClassGroupTempService.lambdaUpdate()
                .eq(SubClassGroupTemp::getTaskId, taskId)
                .eq(SubClassGroupTemp::getUniqueShiftSign, uuid)
                .in(SubClassGroupTemp::getId, ids)
                .set(SubClassGroupTemp::getUniqueGroupSign, null)
                .set(SubClassGroupTemp::getGroupName, null)
                .update();

        return true;
    }

    @Override
    public List<TeachingClassTeacher> groupClassTeacher(Integer taskId, String uuid, Long courseId, List<Teacher> teacherList) {
        List<TeachingClass> teachingClassList = teachingClassService.lambdaQuery()
                .eq(TeachingClass::getUniqueShiftSign, uuid)
                .eq(TeachingClass::getCourseId, courseId).list();
        List<Long> ids = teachingClassList.stream().map(TeachingClass::getTeachingClassId).collect(Collectors.toList());
        List<TeachingClassTeacher> teachingClassTeacherList = new ArrayList<>();
        //教学班对应教师
        teachingClassTeacherService.lambdaUpdate().in(TeachingClassTeacher::getTeachingClassId, ids).remove();
        List<Teacher> teacherList1 = teacherService.lambdaQuery().eq(Teacher::getTaskId, taskId).list();
        for (Long teachingClassId : ids) {
            List<Integer> hourTypes = teachingClassWeekService.lambdaQuery()
                    .eq(TeachingClassWeek::getTeachingClassId, teachingClassId)
                    .list()
                    .stream().map(TeachingClassWeek::getHourType).collect(Collectors.toList());
            for (Teacher item : teacherList) {
                for (Integer type : hourTypes) {
                    //创建教学班-教师实体类
                    TeachingClassTeacher view = new TeachingClassTeacher()
                            .setTeachingClassId(teachingClassId)
                            .setHourType(type);
                    //判断教师表是否存在该教师
                    Optional<Teacher> optional = teacherList1.stream().filter(a -> a.getBaseTeacherId().equals(item.getBaseTeacherId())).findFirst();
                    if (optional.isPresent()) {
                        //存在则获取id
                        if (!optional.get().getIdentity().equals(item.getIdentity()) && item.getIdentity() == 1) {
                            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                            throw new BizException(item.getTeacherName() + ",该老师不是任课教师");
                        } else if (!optional.get().getIdentity().equals(item.getIdentity()) && item.getIdentity() == 2) {
                            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                            throw new BizException(item.getTeacherName() + ",该老师不是助教教师");
                        }
                        view.setTeacherId(optional.get().getTeacherId());
                    } else {
                        //不存在先保存到教师表，再获取id
                        teacherService.save(item);
                        view.setTeacherId(item.getTeacherId());
                    }
                    //保存实体类
                    teachingClassTeacherList.add(view);
                }
            }
        }
        teachingClassTeacherMapper.addBatch(teachingClassTeacherList);
        return teachingClassTeacherList;
    }

    @Override
    public List<TeachingClassWeek> groupClassWeek(String uuid, Long courseId, Long roomId, Integer roomType) {
        List<TeachingClass> teachingClassList = teachingClassService.lambdaQuery()
                .eq(TeachingClass::getUniqueShiftSign, uuid)
                .eq(TeachingClass::getCourseId, courseId).list();
        List<Long> ids = teachingClassList.stream().map(TeachingClass::getTeachingClassId).collect(Collectors.toList());
        List<TeachingClassWeek> weekList = teachingClassWeekService.lambdaQuery().in(TeachingClassWeek::getTeachingClassId, ids).list();
        List<Room> rooms = roomService.lambdaQuery().list();
        List<Type> types = typeService.lambdaQuery().list();
        for (TeachingClassWeek week : weekList) {
            if (roomId != null) {
                week.setRoomId(roomId);
                Room room = rooms.stream().filter(a -> a.getRoomId().equals(roomId)).findFirst().get();
                week.setRoomName(room.getRoomName());
                if (room.getRoomType() != null) {
                    week.setRoomType(room.getRoomType());
                    week.setRoomTypeName(room.getRoomTypeName());
                }
            }
            if (roomType != null) {
                week.setRoomType(roomType);
                week.setRoomTypeName(types.stream().filter(a -> a.getTypeId().equals(roomType)).findFirst().get().getTypeName());
            }
        }
        teachingClassWeekService.saveOrUpdateBatch(weekList);
        return weekList;
    }

    @Override
    public Boolean deleteGroupClassCourse(Integer taskId, String uuid) {
        List<Long> ids = teachingClassService.lambdaQuery()
                .eq(TeachingClass::getTaskId, taskId)
                .eq(TeachingClass::getUniqueShiftSign, uuid)
                .list()
                .stream().map(TeachingClass::getTeachingClassId).collect(Collectors.toList());
        teachingClassService.lambdaUpdate()
                .eq(TeachingClass::getTaskId, taskId)
                .eq(TeachingClass::getUniqueShiftSign, uuid)
                .remove();
        if (CollUtil.isNotEmpty(ids)) {
            teachingClassWeekService.lambdaUpdate()
                    .in(TeachingClassWeek::getTeachingClassId, ids)
                    .remove();
            teachingClassTeacherService.lambdaUpdate()
                    .in(TeachingClassTeacher::getTeachingClassId, ids)
                    .remove();
            teachingClassStudentService.lambdaUpdate()
                    .in(TeachingClassStudent::getTeachingClassId, ids)
                    .remove();
        }
        subClassGroupTempService.lambdaUpdate()
                .eq(SubClassGroupTemp::getUniqueShiftSign, uuid)
                .remove();
        subClassGroupService.lambdaUpdate()
                .eq(SubClassGroup::getUniqueShiftSign, uuid)
                .remove();
        return true;
    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public void importConfirmTeachingTask(HttpServletResponse response, Integer taskId, Integer flag, MultipartFile file) {


        boolean b = checkFile(file);
        if (!b) {
            throw new BizException("该文件不是excel文件");
        }


        List<ErrorExcelVo> errorExcelVos = new ArrayList<>();

        List<ExcelTeachingDto> excel = this.readTeachingClassToExcel(file);

        //通过教学班名称匹配学生

        List<ExcelTeachingStudentDto> teachingStudentDtos = new ArrayList<>();
        if (flag == 2) {
            teachingStudentDtos = this.readTeachingClassStudentToExcel(file);
        }


        checkExcel(excel, errorExcelVos);

        if (CollUtil.isNotEmpty(errorExcelVos)) {
            String time = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy_MM_dd_HH_mm_ss"));

            response.setCharacterEncoding("UTF-8");
            response.setHeader("content-Type", "application/vnd.ms-excel; charset=utf-8");
            MyExcelUtils.exportExcel(errorExcelVos,
                    "导入教学任务错误信息",
                    "错误信息",
                    ErrorExcelVo.class,
                    "导入教学任务错误信息" + time + ".xls", response);
            return;
        }


        //导入该计划对应的教学班
        List<TeachingClass> teachingClasses = teachingClassMapper.selectList(new LambdaQueryWrapper<TeachingClass>()
                .eq(TeachingClass::getTaskId, taskId));


        List<AssessmentMethod> list1 = assessmentMethodService.lambdaQuery().eq(AssessmentMethod::getTaskId, taskId).list();


        Map<String, Course> courseMap = courseService.lambdaQuery().eq(Course::getTaskId, taskId)
                .list()
                .stream().collect(Collectors.toMap(Course::getCourseName, course -> course));


        List<Student> students = studentService.lambdaQuery().eq(Student::getTaskId, taskId).list();

        List<MajorGrade> majorGrades = majorGradeService.lambdaQuery().eq(MajorGrade::getTaskId, taskId).list();

        Map<String, List<MajorGrade>> gradeMap = majorGrades.stream().collect(Collectors.groupingBy(MajorGrade::getGradeName));
        Map<String, List<MajorGrade>> majorMap = majorGrades.stream().collect(Collectors.groupingBy(MajorGrade::getMajorName));


        //获取教师信息
        Map<String, Teacher> teacherMap = teacherService.lambdaQuery().eq(Teacher::getTaskId, taskId)
                .list().stream().collect(Collectors.toMap(Teacher::getBaseTeacherId, Function.identity()));

        Map<String, Integer> campusMap = campusService.lambdaQuery().eq(Campus::getTaskId, taskId).list().stream().collect(Collectors.toMap(Campus::getCampusName, Campus::getCampusId, (o1, o2) -> o1));


        Map<String, Room> roomMap = roomService.lambdaQuery().eq(Room::getTaskId, taskId)
                .list()
                .stream().distinct().collect(Collectors.toMap(Room::getRoomName, Function.identity(), (o1, o2) -> o1));

        Map<String, Integer> typeMap = typeService.lambdaQuery().eq(Type::getTaskId, taskId).eq(Type::getTypeMode, 2).list().stream()
                .collect(Collectors.toMap(Type::getTypeName, Type::getTypeMode, (o1, o2) -> o1));


        //待插入数据 教学班 教学班对应学生 教学班对应教师 教学班参数设置
        List<TeachingClass> teachingClassList = new ArrayList<>();
        List<TeachingClassStudent> teachingClassStudentList = new ArrayList<>();
        List<TeachingClassTeacher> teachingClassTeacherList = new ArrayList<>();
        List<TeachingClassWeek> teachingClassWeekList = new ArrayList<>();

        List<Long> deleteTeachingClassIds = new ArrayList<>();


        //记录当前行数
        long index = 3;
        for (ExcelTeachingDto excelTeachingClass : excel) {
            //存储当前行唯一标识
            excelTeachingClass.setIndex(index);
            index++;
        }


        Map<String, List<ExcelTeachingDto>> teachingClassMap = excel.stream().collect(Collectors.groupingBy(ExcelTeachingDto::getTeachingClassName));


        List<ExcelTeachingStudentDto> finalTeachingStudentDtos = teachingStudentDtos;
        List<ExcelTeachingStudentDto> finalTeachingStudentDtos1 = teachingStudentDtos;
        teachingClassMap.forEach((key, value) -> {
            List<ErrorExcelVo> errorExcelVos1 = new ArrayList<>();
            value.forEach(v -> {
                if (!courseMap.containsKey(v.getCourseName().trim())) {
                    ErrorExcelVo errorExcelVo = new ErrorExcelVo();
                    errorExcelVo.setErrorIndex(v.getIndex());
                    errorExcelVo.setErrorMsg("课程没有在课程库开启" + v.getCourseName());
                    errorExcelVos1.add(errorExcelVo);
                }


                if (StrUtil.isBlank(v.getRoomType())) {
                    ErrorExcelVo errorExcelVo = new ErrorExcelVo();
                    errorExcelVo.setErrorIndex(v.getIndex());
                    errorExcelVo.setErrorMsg("上课场地类型未设置" + v.getTeachingClassName());
                    errorExcelVos1.add(errorExcelVo);
                }


                if (!gradeMap.containsKey(v.getGradeName().trim())) {
                    ErrorExcelVo errorExcelVo = new ErrorExcelVo();
                    errorExcelVo.setErrorIndex(v.getIndex());
                    errorExcelVo.setErrorMsg("年级未设置" + v.getGradeName());
                    errorExcelVos1.add(errorExcelVo);
                }

                if (!majorMap.containsKey(v.getMajorName().trim())) {
                    ErrorExcelVo errorExcelVo = new ErrorExcelVo();
                    errorExcelVo.setErrorIndex(v.getIndex());
                    errorExcelVo.setErrorMsg("专业未设置" + v.getMajorName());
                    errorExcelVos1.add(errorExcelVo);
                }

                if (StrUtil.isBlank(v.getCampusName())) {
                    ErrorExcelVo errorExcelVo = new ErrorExcelVo();
                    errorExcelVo.setErrorIndex(v.getIndex());
                    errorExcelVo.setErrorMsg("上课校区未设置" + v.getTeachingClassName());
                    errorExcelVos1.add(errorExcelVo);
                } else {
                    if (campusMap.get(v.getCampusName()) == null) {
                        ErrorExcelVo errorExcelVo = new ErrorExcelVo();
                        errorExcelVo.setErrorIndex(v.getIndex());
                        errorExcelVo.setErrorMsg("上课校区不存在" + v.getTeachingClassName() + v.getCampusName());
                        errorExcelVos1.add(errorExcelVo);

                    }

                }

                if (StrUtil.isNotBlank(v.getRoomName()) && roomMap.get(v.getRoomName()) == null) {
                    ErrorExcelVo errorExcelVo = new ErrorExcelVo();
                    errorExcelVo.setErrorIndex(v.getIndex());
                    errorExcelVo.setErrorMsg("上课场地不存在" + v.getRoomName());
                    errorExcelVos1.add(errorExcelVo);
                }


                if (StrUtil.isBlank(v.getClassName())) {
                    List<String> baseStudentIds = finalTeachingStudentDtos1.stream().filter(p -> p.getTeachingClassName().equals(v.getTeachingClassName())).map(ExcelTeachingStudentDto::getBaseStudentId).collect(Collectors.toList());
                    if (CollUtil.isNotEmpty(baseStudentIds)) {
                        List<Student> studentList = students.stream().filter(p -> baseStudentIds.contains(p.getBaseStudentId())).collect(Collectors.toList());
                        if (CollUtil.isEmpty(studentList)) {
                            ErrorExcelVo errorExcelVo = new ErrorExcelVo();
                            errorExcelVo.setErrorIndex(v.getIndex());
                            errorExcelVo.setErrorMsg("班级学生未录入" + v.getTeachingClassName());
                            errorExcelVos1.add(errorExcelVo);
                        }
                    } else {
                        ErrorExcelVo errorExcelVo = new ErrorExcelVo();
                        errorExcelVo.setErrorIndex(v.getIndex());
                        errorExcelVo.setErrorMsg("班级学生为添加" + v.getTeachingClassName());
                        errorExcelVos1.add(errorExcelVo);
                    }
                }


            });

            if (CollUtil.isNotEmpty(errorExcelVos1)) {
                errorExcelVos.addAll(errorExcelVos1);
            }

            if (CollUtil.isEmpty(errorExcelVos1)) {

                ExcelTeachingDto excelTeachingDto = value.get(0);

                List<Student> studentList = new ArrayList<>();

                String classId = "";
                String className = "";
                //教学班和行政班相同
                if (StringUtils.isNotBlank(excelTeachingDto.getClassName())) {
                    studentList = students.stream().filter(p -> p.getClassName().equals(excelTeachingDto.getClassName()) && p.getGradeName().equals(excelTeachingDto.getGradeName())).collect(Collectors.toList());
                    Student student = studentList.get(0);
                    classId = student.getClassId();
                    className = student.getClassName();
                } else {
                    List<String> baseStudentId = finalTeachingStudentDtos.stream().filter(p -> p.getTeachingClassName().equals(excelTeachingDto.getTeachingClassName())).map(ExcelTeachingStudentDto::getBaseStudentId).collect(Collectors.toList());

                    if (CollUtil.isNotEmpty(baseStudentId)) {
                        studentList = students.stream().filter(p -> baseStudentId.contains(p.getBaseStudentId())).collect(Collectors.toList());
                    }
                }

                List<TeachingClass> teachingClassList1 = teachingClasses.stream().filter(p -> p.getTeachingClassName().equals(excelTeachingDto.getTeachingClassName())).collect(Collectors.toList());
                if (CollUtil.isNotEmpty(teachingClassList1)) {
                    List<Long> teachingClassIds = teachingClassList1.stream().map(TeachingClass::getTeachingClassId).collect(Collectors.toList());
                    deleteTeachingClassIds.addAll(teachingClassIds);

                }

                List<Long> studentIds = studentList.stream().map(Student::getStudentId).collect(Collectors.toList());


                AssessmentMethod assessmentMethod = list1.stream().filter(p -> p.getAssessmentName().equals(excelTeachingDto.getAssessment())).findFirst().orElse(null);


                teachingClassList.add(new TeachingClass().setTaskId(taskId)
                        .setTeachingClassId(excelTeachingDto.getIndex())
                        .setTeachingClassName(excelTeachingDto.getTeachingClassName())
                        .setCourseId(courseMap.get(excelTeachingDto.getCourseName()).getCourseId())
                        .setCourseName(excelTeachingDto.getCourseName())
                        .setBaseMajorId(majorMap.get(excelTeachingDto.getMajorName()).get(0).getBaseMajorId())
                        .setMajorName(excelTeachingDto.getMajorName())
                        .setBaseCollegeId(courseMap.get(excelTeachingDto.getCourseName()).getBaseCollegeId())
                        .setStudyNature(courseMap.get(excelTeachingDto.getCourseName()).getCourseNature())
                        .setMajorProp(courseMap.get(excelTeachingDto.getCourseName()).getMajorProp())
                        .setCollegeName(courseMap.get(excelTeachingDto.getCourseName()).getCollegeName())
                        .setAssessmentId(ObjUtil.isNotNull(assessmentMethod) ? assessmentMethod.getAssessmentId() : null)
                        .setAssessmentName(ObjUtil.isNotNull(assessmentMethod) ? assessmentMethod.getAssessmentName() : null)
                        .setGradeId(gradeMap.get(excelTeachingDto.getGradeName()).get(0).getGradeId())
                        .setGradeName(excelTeachingDto.getGradeName())
                        .setTeachingClassType(0)
                        .setToClass(classId)
                        .setToClassName(className)
                        .setCampusId(campusMap.get(excelTeachingDto.getCampusName()))
                        .setCampusName(excelTeachingDto.getCampusName())
                        .setFlag(courseMap.get(excelTeachingDto.getCourseName()).getFlag())
                        .setIsOptional(0)
                        .setClassNum(studentList.size()));


                //待插入教学班对应学生 该行政班学生及改学号学生
                if (CollUtil.isNotEmpty(studentIds)) {
                    for (Long studentId : studentIds) {
                        teachingClassStudentList.add(new TeachingClassStudent().setTeachingClassId(excelTeachingDto.getIndex())
                                .setCourseId(courseMap.get(excelTeachingDto.getCourseName()).getCourseId())
                                .setStudentId(studentId)
                                .setFlag(1));
                    }
                }


                WeekDateVo dateVo = taskInfoService.countWeek(taskId);

                StringBuilder str = new StringBuilder();
                for (long i = 0; i < dateVo.getWeekCount(); i++) {
                    str.append("1");
                }

                value.forEach(o -> {
                    TeachingClassWeek teachingClassWeek = new TeachingClassWeek();
                    teachingClassWeek.setTeachingClassId(excelTeachingDto.getIndex());
                    String s = o.getWeek();
                    String[] parts = s.split("-");
                    int num1 = Integer.parseInt(parts[0]);
                    int num2 = Integer.parseInt(parts[1]);
                    StringBuilder sb = new StringBuilder();
                    for (long i = 0; i < dateVo.getWeekCount(); i++) {

                        if (i < (num1 - 1)) {
                            sb.append("0");
                        }
                        if (i >= (num1 - 1) && i <= (num2 - 1)) {
                            sb.append("1");
                        }
                        if (i > (num2 - 1)) {
                            sb.append("0");
                        }
                    }

                    int weekNum = num2 - num1 + 1;
                    teachingClassWeek.setWeek(sb.toString());
                    teachingClassWeek.setTotalHour(o.getHour());
                    teachingClassWeek.setWeekNum(o.getHour() / weekNum);
                    teachingClassWeek.setConnectSection(o.getConnectSection());
                    teachingClassWeek.setConnectNumber(o.getConnectNumber());
                    teachingClassWeek.setHourType(o.getHourType());

                    teachingClassWeek.setRoomType(StringUtils.isBlank(o.getRoomName()) ? typeMap.get(o.getRoomType()) : roomMap.get(o.getRoomName()).getRoomType());
                    teachingClassWeek.setRoomTypeName(StringUtils.isBlank(o.getRoomName()) ? o.getRoomType() : roomMap.get(o.getRoomName()).getRoomTypeName());
                    teachingClassWeek.setRoomId(StringUtils.isBlank(o.getRoomName()) ? null : roomMap.get(o.getRoomName()).getRoomId());
                    teachingClassWeek.setRoomName(StringUtils.isBlank(o.getRoomName()) ? null : roomMap.get(o.getRoomName()).getRoomName());
                    teachingClassWeek.setHourType(o.getHourType());
                    teachingClassWeekList.add(teachingClassWeek);

                    if (StringUtils.isNotBlank(o.getTeacherNo())) {
                        TeachingClassTeacher teachingClassTeacher = new TeachingClassTeacher();
                        teachingClassTeacher.setTeachingClassId(excelTeachingDto.getIndex());
                        teachingClassTeacher.setTeacherId(teacherMap.get(o.getTeacherNo()).getTeacherId());
                        teachingClassTeacher.setHourType(o.getHourType());
                        teachingClassTeacherList.add(teachingClassTeacher);
                    }

                    if (StringUtils.isNotBlank(o.getAssistantTeacherNo())) {

                        TeachingClassTeacher teachingClassTeacher1 = new TeachingClassTeacher();
                        teachingClassTeacher1.setTeachingClassId(excelTeachingDto.getIndex());
                        teachingClassTeacher1.setTeacherId(teacherMap.get(o.getAssistantTeacherNo()).getTeacherId());
                        teachingClassTeacher1.setHourType(o.getHourType());
                        teachingClassTeacherList.add(teachingClassTeacher1);
                    }
                });
            }
        });


        Integer size1 = errorExcelVos.size();

        if (CollUtil.isNotEmpty(errorExcelVos)) {
            String time = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy_MM_dd_HH_mm_ss"));

            response.setCharacterEncoding("UTF-8");
            response.setHeader("content-Type", "application/vnd.ms-excel; charset=utf-8");

            MyExcelUtils.exportExcel(errorExcelVos,
                    "导入教学任务错误信息",
                    "错误信息",
                    ErrorExcelVo.class,
                    "导入教学任务错误信息" + time + ".xls", response);
        }

        //插入教学班
        if (size1.equals(0)) {
            List<TeachingClass> list = teachingClassService.lambdaQuery().orderByDesc(TeachingClass::getTeachingClassId).list();

            Long teachingClassId = 0L;

            if (CollUtil.isNotEmpty(list)) {
                TeachingClass teachingClass = list.get(0);
                teachingClassId = teachingClass.getTeachingClassId();
            }


            Long finalTeachingClassId = teachingClassId;
            teachingClassList.forEach(o -> {
                o.setTeachingClassId(o.getTeachingClassId() + finalTeachingClassId);
            });

            teachingClassWeekList.forEach(o -> {
                o.setTeachingClassId(o.getTeachingClassId() + finalTeachingClassId);
            });

            teachingClassTeacherList.forEach(o -> {
                o.setTeachingClassId(o.getTeachingClassId() + finalTeachingClassId);
            });

            teachingClassStudentList.forEach(o -> {
                o.setTeachingClassId(o.getTeachingClassId() + finalTeachingClassId);
            });
            teachingClassService.saveBatch(teachingClassList);
            teachingClassWeekService.saveOrUpdateBatch(teachingClassWeekList);
            teachingClassTeacherService.saveOrUpdateBatch(teachingClassTeacherList);
            teachingClassStudentService.saveOrUpdateBatch(teachingClassStudentList);

            if (CollUtil.isNotEmpty(deleteTeachingClassIds)) {
                teachingClassService.lambdaUpdate().in(TeachingClass::getTeachingClassId, deleteTeachingClassIds).remove();
            }
        }


    }

    private List<ExcelTeachingStudentDto> readTeachingClassStudentToExcel(MultipartFile file) {
        List<ExcelTeachingStudentDto> excelTeachingClassDtos = new ArrayList<>();

        List<String> expectedHeaders = Arrays.asList(
                "教学班名称", "学号", "学生姓名");
        try {
            InputStream inputStream = file.getResource().getInputStream();
            ExcelReader reader = ExcelUtil.getReader(inputStream, 1);
            //读取表头 判断是否符合预期
            List<String> actualHeaders = reader.readRow(1).stream()
                    .map(Object::toString).filter(StringUtils::isNotBlank).collect(Collectors.toList());
            if (!expectedHeaders.equals(actualHeaders)) {
                throw new BizException(5, "导入模板不匹配，请按照标准模板编辑后导入");
            }

            reader.addHeaderAlias("教学班名称", "teachingClassName");
            reader.addHeaderAlias("学号", "baseStudentId");
            reader.addHeaderAlias("学生姓名", "studentName");

            excelTeachingClassDtos = reader.read(1, 2, ExcelTeachingStudentDto.class);
            reader.close();
        } catch (IOException e) {
            log.info("excel导入教学任务失败:{}", e.getMessage());
        }
        if (excelTeachingClassDtos.size() == 0) {
            throw new BizException(5, "导入数据为空，请检查后重新导入");
        }
        return excelTeachingClassDtos;

    }

    private List<ExcelTeachingDto> readTeachingClassToExcel(MultipartFile file) {
        List<ExcelTeachingDto> excelTeachingClassDtos = new ArrayList<>();

        List<String> expectedHeaders = Arrays.asList(
                "教学班名称", "行政班名称", "课程名称", "院系", "专业", "年级", "校区", "授课方式", "授课学时", "考核类型", "任课教师", "任课教师工号", "助教教师", "助教教师工号", "场地类型", "上课场地", "起止周次", "连上节次", "连上次数");
        try {
            InputStream inputStream = file.getResource().getInputStream();
            ExcelReader reader = ExcelUtil.getReader(inputStream, 0);
            //读取表头 判断是否符合预期
            List<String> actualHeaders = reader.readRow(1).stream()
                    .map(Object::toString).filter(StringUtils::isNotBlank).collect(Collectors.toList());
            if (!expectedHeaders.equals(actualHeaders)) {
                throw new BizException(5, "导入模板不匹配，请按照标准模板编辑后导入");
            }

            reader.addHeaderAlias("教学班名称", "teachingClassName");
            reader.addHeaderAlias("行政班名称", "className");
            reader.addHeaderAlias("课程名称", "courseName");
            reader.addHeaderAlias("院系", "collegeName");
            reader.addHeaderAlias("专业", "majorName");
            reader.addHeaderAlias("年级", "gradeName");
            reader.addHeaderAlias("校区", "campusName");
            reader.addHeaderAlias("授课方式", "hourType");
            reader.addHeaderAlias("授课学时", "hour");
            reader.addHeaderAlias("考核类型", "assessment");
            reader.addHeaderAlias("任课教师", "teacher");
            reader.addHeaderAlias("任课教师工号", "teacherNo");
            reader.addHeaderAlias("助教教师", "assistantTeacher");
            reader.addHeaderAlias("助教教师工号", "assistantTeacherNo");
            reader.addHeaderAlias("场地类型", "roomType");
            reader.addHeaderAlias("上课场地", "roomName");
            reader.addHeaderAlias("起止周次", "week");
            reader.addHeaderAlias("连上节次", "connectSection");
            reader.addHeaderAlias("连上次数", "connectNumber");

            excelTeachingClassDtos = reader.read(1, 2, ExcelTeachingDto.class);
            reader.close();
        } catch (IOException e) {
            log.info("excel导入教学任务失败:{}", e.getMessage());
        }
        if (excelTeachingClassDtos.size() == 0) {
            throw new BizException(5, "导入数据为空，请检查后重新导入");
        }
        return excelTeachingClassDtos;


    }


    private boolean checkFile(MultipartFile file) {

        String contentType = file.getContentType();
        String fileName = file.getOriginalFilename();

        // 检查文件扩展名是否为.xls或.xlsx
        boolean isExcel2003 = fileName.matches("^.+\\.(?i)(xls)$");
        boolean isExcel2007 = fileName.matches("^.+\\.(?i)(xlsx)$");

        // 检查Content-Type
        boolean isExcel = contentType.equals("application/vnd.ms-excel") || contentType.equals("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");


        return isExcel || isExcel2003 || isExcel2007;

    }

    private void checkExcel(List<ExcelTeachingDto> excel, List<ErrorExcelVo> errorExcelVos) {

        long index = 1;

        for (ExcelTeachingDto excelTeachingClass : excel) {
            //存储当前行唯一标识
            excelTeachingClass.setIndex(index);
            index++;
        }

        excel.forEach(o -> {
            if (StringUtils.isBlank(o.getTeachingClassName())) {
                ErrorExcelVo errorExcelVo = new ErrorExcelVo();
                errorExcelVo.setErrorIndex(o.getIndex());
                errorExcelVo.setErrorMsg("第" + o.getIndex() + "行教学班名称不能为空");
                errorExcelVos.add(errorExcelVo);
            }


            if (StringUtils.isBlank(o.getCourseName())) {
                ErrorExcelVo errorExcelVo = new ErrorExcelVo();
                errorExcelVo.setErrorIndex(o.getIndex());
                errorExcelVo.setErrorMsg("第" + o.getIndex() + "行课程名称不能为空");
                errorExcelVos.add(errorExcelVo);
            }


        });
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void importGroupClass(HttpServletResponse response, Integer taskId, Integer flag, MultipartFile file) {

        boolean fileFlag = checkFile(file);
        if (!fileFlag) {
            throw new BizException("该文件不是excel文件");
        }

        List<ExcelSubClass> excelSubClassList = this.readSubClassExcel(file);

        if (CollUtil.isNotEmpty(excelSubClassList)) {
            List<TeachingClass> teachingClassList = teachingClassMapper.selectList(new LambdaQueryWrapper<TeachingClass>()
                    .eq(TeachingClass::getTaskId, taskId));

            if (CollUtil.isNotEmpty(teachingClassList)) {
                List<ErrorExcelVo> errorExcelVos2 = new ArrayList<>();
                List<String> collect = teachingClassList.stream().map(TeachingClass::getTeachingClassName).distinct().collect(Collectors.toList());
                excelSubClassList.forEach(o -> {
                    if (collect.contains(o.getTeachingClassName())) {

                        ErrorExcelVo errorExcelVo = new ErrorExcelVo();
                        errorExcelVo.setErrorIndex(1L);
                        errorExcelVo.setErrorMsg(o.getTeachingClassName() + "教学班名称重复");
                        errorExcelVos2.add(errorExcelVo);
                    }

                    if (CollUtil.isNotEmpty(errorExcelVos2)) {
                        String time = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy_MM_dd_HH_mm_ss"));
                        response.setCharacterEncoding("UTF-8");
                        response.setHeader("content-Type", "application/vnd.ms-excel; charset=utf-8");

                        MyExcelUtils.exportExcel(errorExcelVos2,
                                "分组导入错误信息",
                                "错误信息",
                                ErrorExcelVo.class,
                                "分组导入错误信息" + time + ".xls", response);
                        return;
                    }
                });
            }
        }


        List<ErrorExcelVo> errorExcelVos = new ArrayList<>();


        //获取课程信息
        List<String> courseNames = excelSubClassList.stream().map(ExcelSubClass::getCourseName).distinct().collect(Collectors.toList());

        Map<String, Course> courseMap = courseService.lambdaQuery().eq(Course::getTaskId, taskId)
                .in(Course::getCourseName, courseNames).list()
                .stream().collect(Collectors.toMap(Course::getCourseName, Function.identity()));


        AssessmentMethod assessmentMethod = new AssessmentMethod();
        assessmentMethod = assessmentMethodService.lambdaQuery().eq(AssessmentMethod::getTaskId, taskId).eq(AssessmentMethod::getAssessmentName, "考试").one();


        //获取学生信息
        Set<ExcelStudent> studentList = studentMapper.getStudentList(taskId);

        Map<String, Long> studentIdMap = studentList.stream().collect(Collectors.toMap(ExcelStudent::getBaseStudentId, ExcelStudent::getStudentId));
        //获取教师信息
        Map<String, Teacher> teacherMap = teacherService.lambdaQuery().eq(Teacher::getTaskId, taskId).list().stream().collect(Collectors.toMap(Teacher::getBaseTeacherId, Function.identity()));


        //获取教室信息
        Map<String, Room> roomMap = roomService.lambdaQuery().eq(Room::getTaskId, taskId).list().stream().collect(Collectors.toMap(Room::getRoomName, Function.identity()));


        List<CourseWeek> weekList = courseWeekService.lambdaQuery().eq(CourseWeek::getTaskId, taskId).list();


        List<SubClass> subClasses = new ArrayList<>();
        //待插入数据 教学班 教学班对应学生 教学班对应教师 教学班参数设置
        List<TeachingClass> teachingClassList = new ArrayList<>();
        List<TeachingClassStudent> teachingClassStudentList = new ArrayList<>();
        List<TeachingClassTeacher> teachingClassTeacherList = new ArrayList<>();
        List<TeachingClassWeek> teachingClassWeekList = new ArrayList<>();
        //记录当前行数
        long index = 3;
        for (ExcelSubClass excelTeachingClass : excelSubClassList) {
            //存储当前行唯一标识
            excelTeachingClass.setTeachingClassId(index);
            index++;
        }


        //拆班教学班分组。常规拆班根据课程分组 单双号拆班根据行政班分组
        Map<String, List<ExcelSubClass>> subClassMap = excelSubClassList.stream().collect(Collectors.groupingBy(ExcelSubClass::getClassName));

        for (List<ExcelSubClass> value : subClassMap.values()) {


            List<ErrorExcelVo> errorExcelVos1 = new ArrayList<>();

            //subClass表所需数据
            String uuid = UUID.randomUUID().toString();
            AtomicReference<Integer> totalWeekNum = new AtomicReference<>(0);
            AtomicReference<Integer> max = new AtomicReference<>(0);

            Map<String, List<ExcelSubClass>> collect2 = value.stream().collect(Collectors.groupingBy(ExcelSubClass::getCourseName));


            if (collect2.size() > 1) {
                collect2.forEach((k, v) -> {
                    Integer count = 0;

                    List<CourseWeek> courseWeeks = weekList.stream().filter(p -> p.getCourseId().equals(courseMap.get(k).getCourseId())).collect(Collectors.toList());

                    for (CourseWeek courseWeek : courseWeeks) {
                        count += courseWeek.getWeekNum();

                    }
                    max.set(Math.max(count, max.get()));
                    Integer finalCount = count;
                    totalWeekNum.updateAndGet(v1 -> v1 + finalCount);
                });
                Integer otherWeekNum = totalWeekNum.get() - max.get();

                ExcelSubClass excelSubClass = value.get(0);

                if (max.get() > otherWeekNum) {
                    ErrorExcelVo errorExcelVo = new ErrorExcelVo();
                    errorExcelVo.setErrorIndex(excelSubClass.getTeachingClassId());
                    errorExcelVo.setErrorMsg("年级" + excelSubClass.getGradeName() + "拆班班级" + excelSubClass.getClassName() + "不满足最大课程周学时小于等于其他课程周学时之和");
                    errorExcelVos1.add(errorExcelVo);
                } else {
                    checkSub(value, errorExcelVos1);
                }
            } else {

                Map<String, Object> error = new HashMap<>();
                collect2.forEach((k, v) -> {
                    List<CourseWeek> courseWeeks = weekList.stream().filter(p -> p.getCourseId().equals(courseMap.get(k).getCourseId())).collect(Collectors.toList());

                    courseWeeks.forEach(o -> {
                        totalWeekNum.set(totalWeekNum.get() + o.getWeekNum());
                    });

                    ExcelSubClass excelSubClass = v.get(0);

                    if (totalWeekNum.get() % 2 != 0) {
                        ErrorExcelVo errorExcelVo = new ErrorExcelVo();
                        errorExcelVo.setErrorIndex(excelSubClass.getTeachingClassId());
                        errorExcelVo.setErrorMsg("年级" + excelSubClass.getGradeName() + "拆班班级" + excelSubClass.getCourseName() + "不满足最大课程周学时小于等于其他课程周学时之和");
                        errorExcelVos1.add(errorExcelVo);
                    }
                    List<String> collect7 = value.stream().map(ExcelSubClass::getRoomName).map(String::trim).distinct().collect(Collectors.toList());
                    if (!CollUtil.isEmpty(collect7) && collect7.size() == 1) {
                        ErrorExcelVo errorExcelVo = new ErrorExcelVo();
                        errorExcelVo.setErrorIndex(excelSubClass.getTeachingClassId());
                        errorExcelVo.setErrorMsg("同课程单班双班教室应不相同");
                        errorExcelVos1.add(errorExcelVo);
                    }
                });
            }

            if (CollUtil.isNotEmpty(errorExcelVos1)) {
                errorExcelVos.addAll(errorExcelVos1);
            }

            if (errorExcelVos1.size() == 0) {
                //单班级拆班
                for (ExcelSubClass excelTeachingClass : value) {

                    if (StrUtil.isBlank(excelTeachingClass.getClassName())) {

                        ErrorExcelVo errorExcelVo = new ErrorExcelVo();
                        errorExcelVo.setErrorIndex(excelTeachingClass.getTeachingClassId());
                        errorExcelVo.setErrorMsg("第" + excelTeachingClass.getTeachingClassId() + "行拆班班级名称不能为空");
                        errorExcelVos1.add(errorExcelVo);
                    }

                    //待插入教学班对应教师
                    if (StrUtil.isBlank(excelTeachingClass.getTeacherNo())) {

                        ErrorExcelVo errorExcelVo = new ErrorExcelVo();
                        errorExcelVo.setErrorIndex(excelTeachingClass.getTeachingClassId());
                        errorExcelVo.setErrorMsg("第" + excelTeachingClass.getTeachingClassId() + "行教师编号不能为空");
                        errorExcelVos1.add(errorExcelVo);
                    } else {

                        if (!teacherMap.containsKey(excelTeachingClass.getTeacherNo())) {
                            ErrorExcelVo errorExcelVo = new ErrorExcelVo();
                            errorExcelVo.setErrorIndex(excelTeachingClass.getTeachingClassId());
                            errorExcelVo.setErrorMsg("第" + excelTeachingClass.getTeachingClassId() + "行教师编号不存在:" + excelTeachingClass.getTeacherNo());
                            errorExcelVos1.add(errorExcelVo);
                        } else {
                            if (!teacherMap.get(excelTeachingClass.getTeacherNo()).getIdentity().equals(1)) {
                                ErrorExcelVo errorExcelVo = new ErrorExcelVo();
                                errorExcelVo.setErrorIndex(excelTeachingClass.getTeachingClassId());
                                errorExcelVo.setErrorMsg("第" + excelTeachingClass.getTeachingClassId() + "行教师类型不属于任课教师:" + excelTeachingClass.getTeacherNo());
                                errorExcelVos1.add(errorExcelVo);
                            }
                        }
                    }


                    if (StrUtil.isNotBlank(excelTeachingClass.getRoomName()) && !roomMap.containsKey(excelTeachingClass.getRoomName().trim())) {
                        ErrorExcelVo errorExcelVo = new ErrorExcelVo();
                        errorExcelVo.setErrorIndex(excelTeachingClass.getTeachingClassId());
                        errorExcelVo.setErrorMsg("第" + excelTeachingClass.getTeachingClassId() + "行上课场地不存在:" + excelTeachingClass.getRoomName());
                        errorExcelVos1.add(errorExcelVo);
                    } else {

                        if (ObjUtil.isNull(roomMap.get(excelTeachingClass.getRoomName().trim()).getRoomType())) {
                            ErrorExcelVo errorExcelVo = new ErrorExcelVo();
                            errorExcelVo.setErrorIndex(excelTeachingClass.getTeachingClassId());
                            errorExcelVo.setErrorMsg("第" + excelTeachingClass.getTeachingClassId() + "行上课场地类型未设置:" + excelTeachingClass.getRoomName());
                            errorExcelVos1.add(errorExcelVo);
                        }
                    }
                }
            }


            if (CollUtil.isNotEmpty(errorExcelVos1)) {
                errorExcelVos.addAll(errorExcelVos1);
            }


            if (errorExcelVos1.size() == 0) {

                ExcelSubClass excelSubClass1 = value.get(0);

                Student student = studentMapper.selectList(new LambdaQueryWrapper<Student>().eq(Student::getTaskId, taskId))
                        .stream().filter(p -> p.getClassName().equals(excelSubClass1.getClassName().trim()))
                        .distinct().collect(Collectors.toList()).get(0);


                if (ObjUtil.isNotNull(student)) {
                    SubClass subClass = new SubClass();
                    subClass.setTaskId(taskId);
                    subClass.setClassId(student.getClassId());
                    subClass.setClassName(student.getClassName());
                    subClass.setSubName(student.getClassName() + "分组");
                    List<String> cNames = value.stream().map(ExcelSubClass::getCourseName).distinct().collect(Collectors.toList());
                    List<String> ids = new ArrayList<>();
                    if (CollUtil.isNotEmpty(cNames)) {
                        cNames.forEach(o -> {
                            ids.add(String.valueOf(courseMap.get(o).getCourseId()));
                        });
                    }
                    subClass.setCourseId(String.join("、", ids));
                    subClass.setCourseName(String.join("、", cNames));
                    subClass.setGradeId(student.getGradeId());
                    subClass.setGradeName(student.getGradeName());
                    subClass.setUniqueShiftSign(uuid);
                    subClasses.add(subClass);

                }


                for (ExcelSubClass excelSubClass : value) {

                    List<String> baseStudentIds = new ArrayList<>();
                    List<String> collect3 = studentMapper.selectList(new LambdaQueryWrapper<Student>().eq(Student::getTaskId, taskId))
                            .stream().filter(p -> p.getClassName().equals(excelSubClass.getClassName().trim()))
                            .map(Student::getBaseStudentId).distinct().collect(Collectors.toList());
                    for (String excelStudent : collect3) {
                        String baseStudentId = excelStudent.trim();
                        //根据学生单双号判断是否添加该学生
                        boolean isAdd = ObjUtil.isNull(excelSubClass.getIsSingle()) ||
                                (int) (baseStudentId.charAt(baseStudentId.length() - 1)) % 2 == excelSubClass.getIsSingle() % 2;
                        if (!isAdd) {
                            baseStudentIds.add(baseStudentId);
                        }
                    }

                    List<String> collect = baseStudentIds.stream().distinct().collect(Collectors.toList());


                    //待插入教学班
                    teachingClassList.add(new TeachingClass().setTaskId(taskId)
                            .setTeachingClassId(excelSubClass.getTeachingClassId())
                            .setTeachingClassName(excelSubClass.getTeachingClassName())
                            .setCourseId(courseMap.get(excelSubClass.getCourseName()).getCourseId())
                            .setCourseName(excelSubClass.getCourseName())
                            .setCollegeName(courseMap.get(excelSubClass.getCourseName()).getCollegeName())
                            .setBaseCollegeId(courseMap.get(excelSubClass.getCourseName()).getBaseCollegeId())
                            .setGradeId(student.getGradeId())
                            .setGradeName(student.getGradeName())
                            .setMajorName(student.getMajorName())
                            .setBaseMajorId(student.getMajorId())
                            .setStudyNature(courseMap.get(excelSubClass.getCourseName()).getCourseNature())
                            .setMajorProp(courseMap.get(excelSubClass.getCourseName()).getMajorProp())
                            .setTeachingClassType(0)
                            .setFlag(1)
                            .setCampusId(roomMap.get(excelSubClass.getRoomName()).getCampusId())
                            .setCampusName(roomMap.get(excelSubClass.getRoomName()).getCampusName())
                            .setUniqueShiftSign(uuid)
                            .setIsSingle(excelSubClass.getIsSingle())
                            .setClassNum(collect.size()));

                    WeekDateVo dateVo = taskInfoService.countWeek(taskId);

                    StringBuilder str = new StringBuilder();
                    for (long i = 0; i < dateVo.getWeekCount(); i++) {
                        str.append("1");
                    }
                    String string = str.toString();

                    List<CourseWeek> courseWeeks = weekList.stream().filter(p -> p.getCourseId().equals(courseMap.get(excelSubClass.getCourseName()).getCourseId())).collect(Collectors.toList());


                    courseWeeks.forEach(o -> {
                        TeachingClassWeek teachingClassWeek = new TeachingClassWeek();
                        teachingClassWeek.setTeachingClassId(excelSubClass.getTeachingClassId());
                        teachingClassWeek.setWeek(StringUtils.isNotBlank(o.getWeek()) ? o.getWeek() : string);
                        teachingClassWeek.setTotalHour(o.getTotalHour());
                        teachingClassWeek.setWeekNum(o.getWeekNum());
                        teachingClassWeek.setConnectSection(1);
                        teachingClassWeek.setConnectNumber(1);
                        teachingClassWeek.setRoomType(roomMap.get(excelSubClass.getRoomName()).getRoomType());
                        teachingClassWeek.setRoomTypeName(roomMap.get(excelSubClass.getRoomName()).getRoomTypeName());
                        teachingClassWeek.setRoomId(roomMap.get(excelSubClass.getRoomName()).getRoomId());
                        teachingClassWeek.setRoomName(roomMap.get(excelSubClass.getRoomName()).getRoomName());
                        teachingClassWeek.setHourType(o.getHourType());
                        teachingClassWeekList.add(teachingClassWeek);

                        TeachingClassTeacher teachingClassTeacher = new TeachingClassTeacher();
                        teachingClassTeacher.setTeachingClassId(excelSubClass.getTeachingClassId());
                        teachingClassTeacher.setTeacherId(teacherMap.get(excelSubClass.getTeacherNo()).getTeacherId());
                        teachingClassTeacher.setHourType(o.getHourType());

                        teachingClassTeacherList.add(teachingClassTeacher);

                    });


                    //生成对应学生
                    if (CollUtil.isNotEmpty(collect)) {

                        for (String studentId : collect) {

                            studentId = studentId.trim();
                            teachingClassStudentList.add(new TeachingClassStudent()
                                    .setTeachingClassId(excelSubClass.getTeachingClassId())
                                    .setStudentId(studentIdMap.get(studentId))
                                    .setCourseId(courseMap.get(excelSubClass.getCourseName()).getCourseId())
                                    .setFlag(1));
                        }
                    }
                }
            }
        }


        Integer errorExcelVos1 = errorExcelVos.size();
        if (CollUtil.isNotEmpty(errorExcelVos)) {
            String time = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy_MM_dd_HH_mm_ss"));
            response.setCharacterEncoding("UTF-8");
            response.setHeader("content-Type", "application/vnd.ms-excel; charset=utf-8");

            MyExcelUtils.exportExcel(errorExcelVos,
                    "分组导入错误信息",
                    "错误信息",
                    ErrorExcelVo.class,
                    "分组导入错误信息" + time + ".xls", response);

            throw new BizException("导入模板存在问题");
        }

        if (errorExcelVos1.equals(0)) {
            List<TeachingClass> list = teachingClassService.lambdaQuery().orderByDesc(TeachingClass::getTeachingClassId).list();

            Long teachingClassId = 0L;

            if (CollUtil.isNotEmpty(list)) {
                TeachingClass teachingClass = list.get(0);
                teachingClassId = teachingClass.getTeachingClassId();
            }

            Long finalTeachingClassId = teachingClassId;
            teachingClassList.forEach(o -> {
                o.setTeachingClassId(o.getTeachingClassId() + finalTeachingClassId);
            });

            teachingClassWeekList.forEach(o -> {
                o.setTeachingClassId(o.getTeachingClassId() + finalTeachingClassId);
            });

            teachingClassTeacherList.forEach(o -> {
                o.setTeachingClassId(o.getTeachingClassId() + finalTeachingClassId);
            });

            teachingClassStudentList.forEach(o -> {
                o.setTeachingClassId(o.getTeachingClassId() + finalTeachingClassId);
            });

            teachingClassService.saveBatch(teachingClassList);
            teachingClassWeekService.saveOrUpdateBatch(teachingClassWeekList);
            teachingClassTeacherService.saveOrUpdateBatch(teachingClassTeacherList);
            List<TeachingClassStudent> classStudents = teachingClassStudentList.stream().distinct().collect(Collectors.toList());
            teachingClassStudentService.saveOrUpdateBatch(classStudents);

            //自动分组
            List<String> uuid = teachingClassList.stream().map(TeachingClass::getUniqueShiftSign).distinct().collect(Collectors.toList());
            uuid.forEach(o -> {
                subClassGroupService.autoGroup(taskId, o);
            });

            subClassService.saveOrUpdateBatch(subClasses);


        }
    }


    private List<ExcelSubClass> readSubClassExcel(MultipartFile file) {
        List<ExcelSubClass> excelTeachingClasses = new ArrayList<>();
        List<String> expectedHeaders = Arrays.asList(
                "分组教学班名称", "课程名称", "对应行政班名称", "年级", "单双班", "任课教师工号", "上课场地");
        try {

            InputStream inputStream = file.getResource().getInputStream();
            ExcelReader reader = ExcelUtil.getReader(inputStream, 0);
            //读取表头 判断是否符合预期
            List<String> actualHeaders = reader.readRow(1).stream()
                    .map(Object::toString).filter(StringUtils::isNotBlank)
                    .collect(Collectors.toList());
            if (!expectedHeaders.equals(actualHeaders)) {
                throw new BizException(5, "导入模板不匹配，请按照标准模板编辑后导入");
            }

            reader.addHeaderAlias("分组教学班名称", "teachingClassName");
            reader.addHeaderAlias("课程名称", "courseName");
            reader.addHeaderAlias("年级", "gradeName");
            reader.addHeaderAlias("单双班", "isSingle");
            reader.addHeaderAlias("对应行政班名称", "className");
            reader.addHeaderAlias("任课教师工号", "teacherNo");
            reader.addHeaderAlias("上课场地", "roomName");

            excelTeachingClasses = reader.read(1, 2, ExcelSubClass.class);
            reader.close();
        } catch (Exception ex) {
            log.info("excel导入教学任务失败:{}", ex.getMessage());
        }

        if (excelTeachingClasses.size() == 0) {
            throw new BizException(5, "导入数据为空，请检查后重新导入");
        }

        return excelTeachingClasses;
    }


    private void checkSub(List<ExcelSubClass> value, List<ErrorExcelVo> errorExcelVos) {
        value.forEach(o -> {
            value.forEach(e -> {
                if (!o.getCourseName().equals(e.getCourseName())) {
                    if (o.getTeacherNo().equals(e.getTeacherNo())) {
                        ErrorExcelVo errorExcelVo = new ErrorExcelVo();
                        errorExcelVo.setErrorIndex(o.getTeachingClassId());
                        errorExcelVo.setErrorMsg("年级" + o.getGradeName() + o.getTeachingClassName() + "与年级" + e.getGradeName() + e.getTeachingClassName() + "教师设置不可以相同");
                        errorExcelVos.add(errorExcelVo);
                    }

                    if (StringUtils.isNotBlank(o.getRoomName()) && StringUtils.isNotBlank(e.getRoomName()) && o.getRoomName().equals(e.getRoomName())) {
                        ErrorExcelVo errorExcelVo = new ErrorExcelVo();
                        errorExcelVo.setErrorIndex(o.getTeachingClassId());
                        errorExcelVo.setErrorMsg("年级" + o.getGradeName() + o.getTeachingClassName() + "与年级" + e.getGradeName() + e.getTeachingClassName() + "讲授教室设置不可以相同");
                        errorExcelVos.add(errorExcelVo);
                    }

                }

            });
        });
    }


}
